<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Eigen-unsupported: BVH module</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
</script>
<script type="text/javascript" async="async" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="eigendoxy.css" rel="stylesheet" type="text/css">
<!--  -->
<script type="text/javascript" src="eigen_navtree_hacks.js"></script>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="Eigen_Silly_Professor_64x64.png"/></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname"><a href="http://eigen.tuxfamily.org">Eigen-unsupported</a>
   &#160;<span id="projectnumber">3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)</span>
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.svg"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.1 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('group__BVH__Module.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">BVH module</div>  </div>
</div><!--header-->
<div class="contents">
<p>This module provides generic bounding volume hierarchy algorithms and reference tree implementations. </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;unsupported/Eigen/BVH&gt;</span></div>
</div><!-- fragment --><p>A bounding volume hierarchy (BVH) can accelerate many geometric queries. This module provides a generic implementation of the two basic algorithms over a BVH: intersection of a query object against all objects in the hierarchy and minimization of a function over the objects in the hierarchy. It also provides intersection and minimization over a cartesian product of two BVH's. A BVH accelerates intersection by using the fact that if a query object does not intersect a volume, then it cannot intersect any object contained in that volume. Similarly, a BVH accelerates minimization because the minimum of a function over a volume is no greater than the minimum of a function over any object contained in it.</p>
<p>Some sample queries that can be written in terms of intersection are:</p><ul>
<li>Determine all points where a ray intersects a triangle mesh</li>
<li>Given a set of points, determine which are contained in a query sphere</li>
<li>Given a set of spheres, determine which contain the query point</li>
<li>Given a set of disks, determine if any is completely contained in a query rectangle (represent each 2D disk as a point \((x,y,r)\) in 3D and represent the rectangle as a pyramid based on the original rectangle and shrinking in the \(r\) direction)</li>
<li>Given a set of points, count how many pairs are \(d\pm\epsilon\) apart (done by looking at the cartesian product of the set of points with itself)</li>
</ul>
<p>Some sample queries that can be written in terms of function minimization over a set of objects are:</p><ul>
<li>Find the intersection between a ray and a triangle mesh closest to the ray origin (function is infinite off the ray)</li>
<li>Given a polyline and a query point, determine the closest point on the polyline to the query</li>
<li>Find the diameter of a point cloud (done by looking at the cartesian product and using negative distance as the function)</li>
<li>Determine how far two meshes are from colliding (this is also a cartesian product query)</li>
</ul>
<p>This implementation decouples the basic algorithms both from the type of hierarchy (and the types of the bounding volumes) and from the particulars of the query. To enable abstraction from the BVH, the BVH is required to implement a generic mechanism for traversal. To abstract from the query, the query is responsible for keeping track of results.</p>
<p>To be used in the algorithms, a hierarchy must implement the following traversal mechanism (see <a class="el" href="classEigen_1_1KdBVH.html" title="A simple bounding volume hierarchy based on AlignedBox.">KdBVH</a> for a sample implementation):</p><div class="fragment"><div class="line"><span class="keyword">typedef</span> Volume  <span class="comment">//the type of bounding volume</span></div>
<div class="line"><span class="keyword">typedef</span> Object  <span class="comment">//the type of object in the hierarchy</span></div>
<div class="line"><span class="keyword">typedef</span> <a class="codeRef" href="../namespaceEigen.html#a62e77e0933482dafde8fe197d9a2cfde">Index</a>   <span class="comment">//a reference to a node in the hierarchy--typically an int or a pointer</span></div>
<div class="line"><span class="keyword">typedef</span> VolumeIterator <span class="comment">//an iterator type over node children--returns Index</span></div>
<div class="line"><span class="keyword">typedef</span> ObjectIterator <span class="comment">//an iterator over object (leaf) children--returns const Object &amp;</span></div>
<div class="line"><a class="codeRef" href="../namespaceEigen.html#a62e77e0933482dafde8fe197d9a2cfde">Index</a> getRootIndex() const <span class="comment">//returns the index of the hierarchy root</span></div>
<div class="line">const Volume &amp;getVolume(<a class="codeRef" href="../namespaceEigen.html#a62e77e0933482dafde8fe197d9a2cfde">Index</a> index) const <span class="comment">//returns the bounding volume of the node at given index</span></div>
<div class="line"><span class="keywordtype">void</span> getChildren(<a class="codeRef" href="../namespaceEigen.html#a62e77e0933482dafde8fe197d9a2cfde">Index</a> index, VolumeIterator &amp;outVBegin, VolumeIterator &amp;outVEnd,</div>
<div class="line">                ObjectIterator &amp;outOBegin, ObjectIterator &amp;outOEnd) const</div>
<div class="line"><span class="comment">//getChildren takes a node index and makes [outVBegin, outVEnd) range over its node children</span></div>
<div class="line"><span class="comment">//and [outOBegin, outOEnd) range over its object children</span></div>
<div class="ttc" id="anamespaceEigen_html_a62e77e0933482dafde8fe197d9a2cfde"><div class="ttname"><a href="../namespaceEigen.html#a62e77e0933482dafde8fe197d9a2cfde">Eigen::Index</a></div><div class="ttdeci">EIGEN_DEFAULT_DENSE_INDEX_TYPE Index</div></div>
</div><!-- fragment --><p>To use the hierarchy, call BVIntersect or BVMinimize, passing it a BVH (or two, for cartesian product) and a minimizer or intersector. For an intersection query on a single BVH, the intersector encapsulates the query and must provide two functions: </p><div class="fragment"><div class="line"><span class="keywordtype">bool</span> intersectVolume(<span class="keyword">const</span> Volume &amp;volume) <span class="comment">//returns true if the query intersects the volume</span></div>
<div class="line"><span class="keywordtype">bool</span> intersectObject(<span class="keyword">const</span> Object &amp;<span class="keywordtype">object</span>) <span class="comment">//returns true if the intersection search should terminate immediately</span></div>
</div><!-- fragment --><p> The guarantee that BVIntersect provides is that intersectObject will be called on every object whose bounding volume intersects the query (but possibly on other objects too) unless the search is terminated prematurely. It is the responsibility of the intersectObject function to keep track of the results in whatever manner is appropriate. The cartesian product intersection and the BVMinimize queries are similar&ndash;see their individual documentation.</p>
<p>The following is a simple but complete example for how to use the BVH to accelerate the search for a closest red-blue point pair: </p><div class="fragment"><div class="line"><span class="preprocessor">#include &lt;Eigen/StdVector&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;unsupported/Eigen/BVH&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using namespace </span><a class="code" href="namespaceEigen.html">Eigen</a>;</div>
<div class="line"><span class="keyword">typedef</span> AlignedBox&lt;double, 2&gt; Box2d;</div>
<div class="line"> </div>
<div class="line"><span class="keyword">namespace </span><a class="code" href="namespaceEigen.html">Eigen</a> {</div>
<div class="line">  Box2d bounding_box(<span class="keyword">const</span> <a class="codeRef" href="../group__matrixtypedefs.html#ga6c206cbf6f8f3b74bc63ecd362fc2ad6">Vector2d</a> &amp;v) { <span class="keywordflow">return</span> Box2d(v, v); } <span class="comment">//compute the bounding box of a single point</span></div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keyword">struct </span>PointPointMinimizer <span class="comment">//how to compute squared distances between points and rectangles</span></div>
<div class="line">{</div>
<div class="line">  PointPointMinimizer() : calls(0) {}</div>
<div class="line">  <span class="keyword">typedef</span> <span class="keywordtype">double</span> Scalar;</div>
<div class="line"> </div>
<div class="line">  <span class="keywordtype">double</span> minimumOnVolumeVolume(<span class="keyword">const</span> Box2d &amp;r1, <span class="keyword">const</span> Box2d &amp;r2) { ++calls; <span class="keywordflow">return</span> r1.squaredExteriorDistance(r2); }</div>
<div class="line">  <span class="keywordtype">double</span> minimumOnVolumeObject(<span class="keyword">const</span> Box2d &amp;r, <span class="keyword">const</span> <a class="codeRef" href="../group__matrixtypedefs.html#ga6c206cbf6f8f3b74bc63ecd362fc2ad6">Vector2d</a> &amp;v) { ++calls; <span class="keywordflow">return</span> r.squaredExteriorDistance(v); }</div>
<div class="line">  <span class="keywordtype">double</span> minimumOnObjectVolume(<span class="keyword">const</span> <a class="codeRef" href="../group__matrixtypedefs.html#ga6c206cbf6f8f3b74bc63ecd362fc2ad6">Vector2d</a> &amp;v, <span class="keyword">const</span> Box2d &amp;r) { ++calls; <span class="keywordflow">return</span> r.squaredExteriorDistance(v); }</div>
<div class="line">  <span class="keywordtype">double</span> minimumOnObjectObject(<span class="keyword">const</span> <a class="codeRef" href="../group__matrixtypedefs.html#ga6c206cbf6f8f3b74bc63ecd362fc2ad6">Vector2d</a> &amp;v1, <span class="keyword">const</span> <a class="codeRef" href="../group__matrixtypedefs.html#ga6c206cbf6f8f3b74bc63ecd362fc2ad6">Vector2d</a> &amp;v2) { ++calls; <span class="keywordflow">return</span> (v1 - v2).squaredNorm(); }</div>
<div class="line"> </div>
<div class="line">  <span class="keywordtype">int</span> calls;</div>
<div class="line">};</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line">  <span class="keyword">typedef</span> std::vector&lt;Vector2d, aligned_allocator&lt;Vector2d&gt; &gt; StdVectorOfVector2d;</div>
<div class="line">  StdVectorOfVector2d redPoints, bluePoints;</div>
<div class="line">  <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; 100; ++i) { <span class="comment">//initialize random set of red points and blue points</span></div>
<div class="line">    redPoints.push_back(<a class="codeRef" href="../classEigen_1_1DenseBase.html#ae814abb451b48ed872819192dc188c19">Vector2d::Random</a>());</div>
<div class="line">    bluePoints.push_back(<a class="codeRef" href="../classEigen_1_1DenseBase.html#ae814abb451b48ed872819192dc188c19">Vector2d::Random</a>());</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line">  PointPointMinimizer minimizer;</div>
<div class="line">  <span class="keywordtype">double</span> minDistSq = std::numeric_limits&lt;double&gt;::max();</div>
<div class="line"> </div>
<div class="line">  <span class="comment">//brute force to find closest red-blue pair</span></div>
<div class="line">  <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; (int)redPoints.size(); ++i)</div>
<div class="line">    <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; (int)bluePoints.size(); ++j)</div>
<div class="line">      minDistSq = std::min(minDistSq, minimizer.minimumOnObjectObject(redPoints[i], bluePoints[j]));</div>
<div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;Brute force distance = &quot;</span> &lt;&lt; <a class="codeRef" href="../namespaceEigen.html#af4f536e8ea56702e63088efb3706d1f0">sqrt</a>(minDistSq) &lt;&lt; <span class="stringliteral">&quot;, calls = &quot;</span> &lt;&lt; minimizer.calls &lt;&lt; std::endl;</div>
<div class="line"> </div>
<div class="line">  <span class="comment">//using BVH to find closest red-blue pair</span></div>
<div class="line">  minimizer.calls = 0;</div>
<div class="line">  KdBVH&lt;double, 2, Vector2d&gt; redTree(redPoints.begin(), redPoints.end()), blueTree(bluePoints.begin(), bluePoints.end()); <span class="comment">//construct the trees</span></div>
<div class="line">  minDistSq = <a class="code" href="namespaceEigen.html#adcbe73ac1482eacab0e18ee32c25508e">BVMinimize</a>(redTree, blueTree, minimizer); <span class="comment">//actual BVH minimization call</span></div>
<div class="line">  std::cout &lt;&lt; <span class="stringliteral">&quot;BVH distance         = &quot;</span> &lt;&lt; <a class="codeRef" href="../namespaceEigen.html#af4f536e8ea56702e63088efb3706d1f0">sqrt</a>(minDistSq) &lt;&lt; <span class="stringliteral">&quot;, calls = &quot;</span> &lt;&lt; minimizer.calls &lt;&lt; std::endl;</div>
<div class="line"> </div>
<div class="line">  <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
<div class="ttc" id="aclassEigen_1_1DenseBase_html_ae814abb451b48ed872819192dc188c19"><div class="ttname"><a href="../classEigen_1_1DenseBase.html#ae814abb451b48ed872819192dc188c19">Eigen::DenseBase::Random</a></div><div class="ttdeci">static const RandomReturnType Random()</div></div>
<div class="ttc" id="agroup__matrixtypedefs_html_ga6c206cbf6f8f3b74bc63ecd362fc2ad6"><div class="ttname"><a href="../group__matrixtypedefs.html#ga6c206cbf6f8f3b74bc63ecd362fc2ad6">Vector2d</a></div><div class="ttdeci">Matrix&lt; double, 2, 1 &gt; Vector2d</div></div>
<div class="ttc" id="anamespaceEigen_html"><div class="ttname"><a href="namespaceEigen.html">Eigen</a></div><div class="ttdoc">Namespace containing all symbols from the Eigen library.</div></div>
<div class="ttc" id="anamespaceEigen_html_adcbe73ac1482eacab0e18ee32c25508e"><div class="ttname"><a href="namespaceEigen.html#adcbe73ac1482eacab0e18ee32c25508e">Eigen::BVMinimize</a></div><div class="ttdeci">Minimizer::Scalar BVMinimize(const BVH &amp;tree, Minimizer &amp;minimizer)</div><div class="ttdef"><b>Definition:</b> BVAlgorithms.h:221</div></div>
<div class="ttc" id="anamespaceEigen_html_af4f536e8ea56702e63088efb3706d1f0"><div class="ttname"><a href="../namespaceEigen.html#af4f536e8ea56702e63088efb3706d1f0">Eigen::sqrt</a></div><div class="ttdeci">const Eigen::CwiseUnaryOp&lt; Eigen::internal::scalar_sqrt_op&lt; typename Derived::Scalar &gt;, const Derived &gt; sqrt(const Eigen::ArrayBase&lt; Derived &gt; &amp;x)</div></div>
</div><!-- fragment --><p> Output: </p><pre class="fragment">Brute force distance = 0.00428018, calls = 10000
BVH distance         = 0.00428018, calls = 756
</pre> </div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Thu Apr 21 2022 13:08:00 for Eigen-unsupported by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.9.1 </li>
  </ul>
</div>
</body>
</html>
